﻿using System.Collections;
using System.Security.Cryptography;
using System;
using System.Text;
using UnityEngine;

/// <summary>
/// 131202 hikim
/// </summary>
public class AES {

    public static readonly AES Instance = new AES();

    private readonly RijndaelManaged crypto = new RijndaelManaged();
    private const int KEYSIZE = 128;
    private const int BLOCKSIZE = 128;

    private AES()
    {
        string key = "hikim" + SystemInfo.deviceUniqueIdentifier + "hikim";
        byte[] bytes = Common.Encoding.GetBytes(key);
        byte[] hashedBytes = SHA.Instance.ComputeHash(bytes);
        byte[] keyBytes = new byte[16];
        Array.Copy(hashedBytes, keyBytes, keyBytes.Length);
        Init(keyBytes, keyBytes);
    }

    public AES(string base64key, string base64iv)
    {
        Init(base64key, base64iv);
    }

    public AES(byte[] key, byte[] iv)
    {
        Init(key, iv);
    }

    public void Init(string base64key, string base64iv)
    {
        this.Init(Convert.FromBase64String(base64key), Convert.FromBase64String(base64iv));
    }

    public void Init(byte[] key, byte[] iv)
    {
        this.crypto.Mode = CipherMode.CBC;
        this.crypto.Padding = PaddingMode.PKCS7;
        this.crypto.KeySize = KEYSIZE;
        this.crypto.BlockSize = BLOCKSIZE;
        this.crypto.Key = key;
        this.crypto.IV = iv;
    }

    public string EncryptToBase64(string plainText)
    {
        return Convert.ToBase64String(Encrypt(plainText));
    }

    public byte[] Encrypt(string plainText)
    {
        if (string.IsNullOrEmpty(plainText))
            return null;
        byte[] plainTextBytes = Common.Encoding.GetBytes(plainText);
        return Encrypt(plainTextBytes);
    }

    public string EncryptToBase64(byte[] plainText)
    {
        return Convert.ToBase64String(Encrypt(plainText));
    }

    public byte[] Encrypt(byte[] plainText)
    {
        return crypto.CreateEncryptor().TransformFinalBlock(plainText, 0, plainText.Length);
    }

    public string Decrypt(string base64encrypted)
    {
        if (string.IsNullOrEmpty(base64encrypted))
            return null;
        byte[] encryptedBytes = Convert.FromBase64String(base64encrypted);
        byte[] plainTextBytes = Decrypt(encryptedBytes);
        return Common.Encoding.GetString(plainTextBytes);
    }

    public byte[] Decrypt(byte[] encrypted)
    {
        return crypto.CreateDecryptor().TransformFinalBlock(encrypted, 0, encrypted.Length);
    }
}
